/**
    Copyright (c) 2009 yakiimo02
    Distributed under the New BSD License.
    See included license.txt or http://www.yakiimo3d.com/NewBSDLicense.txt
**/

#pragma once

#include "BitonicSortData.h"

/**
    @brief  CPU implementation of Bitonic Sort that uses loop iteration.
            Based on code from http://www.tools-of-computing.com/tc/CS/Sorts/bitonic_sort.htm
            which I learned about from http://developer.download.nvidia.com/compute/cuda/sdk/website/samples.html
            the Nvidia Cuda SDK Bitonic Sort sample.
    @author yakiimo02
    @date    09/11/28
*/
class BitonicSortCPU
{
public:
    BitonicSortCPU();
    virtual ~BitonicSortCPU();

    virtual void Update();
    virtual void UpdateOnce();
    virtual void SortUp() = 0;
    virtual void SortDown() = 0;

    HRESULT Create( ID3D11Device* pd3dDevice, const BufTypeVector& data );
    void    Destroy();
    void    UpdateBuffer( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext );

    inline ID3D11ShaderResourceView* GetpSRV() { return m_pSRV; }
    
    inline void SetSortUp( bool bSortUp ) { m_bSortUp = bSortUp; }
    inline void SetData( const BufTypeVector& data ) { m_data = data; }

protected:
    inline void Swap( int nIndex0, int nIndex1 );

protected:
    BufTypeVector               m_data;     // data to be sorted

    ID3D11Buffer*               m_pBuffer;
    ID3D11ShaderResourceView*   m_pSRV;

    bool m_bSortUp;                      // whether to sort in increasing order
};

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/**
    Swap nIndex0 m_data with nIndex1 m_data
    @param nIndex0    [in]        index0
    @param nIndex1    [in]        index1
*/
void BitonicSortCPU::Swap( int nIndex0, int nIndex1 )
{
    BufType tmp = m_data[ nIndex0 ];
    m_data[ nIndex0 ] = m_data[ nIndex1 ];
    m_data[ nIndex1 ] = tmp;
}